use bytes::{BufMut, BytesMut};
use nom::bytes::complete::take_while;
use nom::combinator::all_consuming;
use nom::multi::many_till;
use nom::sequence::delimited;
use nom::IResult;

#[derive(Debug)]
pub struct Request {
    args: Vec<String>,
}

impl Request {
    pub fn new() -> Self {
        Request { args: Vec::new() }
    }

    pub fn add_arg(&mut self, arg: &str) {
        self.args.push(arg.to_string());
    }

    pub fn to_bytes(&self) -> BytesMut {
        let mut bytes = BytesMut::new();
        bytes.put(&format!("*{}\r\n", self.args.len()).into_bytes()[..]);
        self.args.iter().for_each(|arg| {
            bytes.put(&format!("${}\r\n", arg.len()).into_bytes()[..]);
            bytes.put(&format!("{}\r\n", arg).into_bytes()[..]);
        });
        bytes
    }

    pub fn parer_request(i: &str) -> IResult<&str, Request> {
        let (i, (vec, _)) = many_till(
            delimited(parse_multispace, parse_not_multispace, parse_multispace),
            all_consuming(parse_multispace),
        )(i)?;
        let mut request = Request::new();
        vec.iter().for_each(|s| request.add_arg(s));
        Ok((i, request))
    }
}

pub fn parse_multispace(i: &str) -> IResult<&str, &str> {
    let chars = " \n\t\r";
    take_while(move |c: char| chars.contains(c))(i)
}

//获取所有的非空字符.除去\t
pub fn parse_not_multispace(i: &str) -> IResult<&str, &str> {
    let chars = " \n\t\r";
    take_while(move |c: char| !chars.contains(c))(i)
}
